<?php

namespace app\admin\controller;

use app\common\controller\Backend;
use app\api\controller\WxPay;
use think\Db;
use think\Session;

/**
 *
 *
 * @icon fa fa-circle-o
 */
class Order extends Backend
{

    /**
     * Order模型对象
     * @var \app\admin\model\Order
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\Order;
        $this->view->assign("payStatusList",$this->model->getStatusList());
        $this->view->assign("payStatusList2",$this->model->getStatusList2());
        $this->view->assign("RefundStatusList",$this->model->getRefundStatusList());


    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        $hid = Session::get("admin")["hotelid"];
        $adminId = Session::get("admin")["id"];

        //带入酒店id 酒店入口
        $ids = $this->request->request("ids");

        $where2 = [];
        if($ids){
            $where2 = " `fa_order`.`hotelid` = $ids";
            $this->assign("ids",$ids);
        }else{
            $this->assign("ids","");
        }

        //带入房间id 房间入口
        $rid = $this->request->request("rid");
        $where3 = [];
        if($rid){
            $where3 = " `fa_order`.`room_id` = $rid";
            $this->assign("rid",$rid);
        }else{
            $this->assign("rid","");
        }

        //带入用户id 用户入口
        $uid = $this->request->request("uid");
        $where4 = [];
        if($uid){
            $where4 = " `fa_order`.`user_id` = $uid";
            $this->assign("uid",$uid);
        }else{
            $this->assign("uid","");
        }

        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax())
        {

            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }


            //初始化默认显示预订和入住的订单
            $filter = (array)$this->request->request('filter');
            list($where, $sort, $order, $offset, $limit,$paystatus) = $this->buildparams();

            if($paystatus == "20"){
                //进行中：预定、入住两种 status = 1 and refund_status = 0 || status = 2 and refund_status = 0
                $where1 = "pay_status = '1' and refund_status = '0' || pay_status = '2' and refund_status = '0'";
            }elseif ($paystatus == "21"){
                //已完成：入住  status = 3 and refund_status = 3 || status = 3 and refund_status = 1 || status = 3 and refund_status = 0
                $where1 = "pay_status = '3' and refund_status = '3' || pay_status = '3' and refund_status = '0' || pay_status = '3' and refund_status = '1'";
            }elseif ($paystatus == "22"){
                //退款：预定 status = 1 and refund_status = 2 || status = 1 and refund_status = 4 || status = 4 and refund_status = 1 || status = 4 and refund_status  = 4 || status = 2 and refund_status  = 2
                $where1 = "pay_status = '1' and refund_status = '2' || pay_status = '1' and refund_status = '4' || pay_status = '4' and refund_status = '1' || pay_status = '4' and refund_status = '4' || pay_status = '2' and refund_status = '2' || pay_status = '4' and refund_status = '3'";
            }elseif ($paystatus == "23"){
                //未支付：未支付、支付失败 status = 0 || status = 5 || (未支付订单的取消) status = 4  and refund_status = 0
                $where1 = "pay_status = '0' || pay_status = '5' || pay_status = '4' and refund_status = '0'";
            }else{
                //全部：所有订单
                $where1 = "";
            }

            if($adminId == 1){
                $total = $this->model
                   // ->with(['house','user','hotel'])
                  // ->with(['user'])
                    ->where($where)
                    ->where($where1)
                    ->where($where2)
                    ->where($where3)
                    ->where($where4)
                    ->order($sort, $order)
                    ->count();


                $list = $this->model
                    ->where($where)
                    ->where($where1)
                    ->where($where2)
                    ->where($where3)
                    ->where($where4)
                    ->order($sort, $order)
                    ->limit($offset, $limit)
                    ->select();

            }else{

                $total = $this->model
                    ->where($where)
                    ->where($where1)
                    ->where($where2)
                    ->where($where3)
                    ->where($where4)
                    ->where("hotelid in ($hid)")
                    ->order($sort, $order)
                    ->count();

                $list = $this->model
                    ->where($where)
                    ->where($where1)
                    ->where($where2)
                    ->where($where3)
                    ->where($where4)
                    ->where("hotelid in ($hid)")
                    ->order($sort, $order)
                    ->limit($offset, $limit)
                    ->select();


            }


           /* foreach ($list as $row) {

               // $row->getRelation('house')->visible(['h_title']);
                //$row->getRelation('hotel')->visible(['h_title']);
				$row->getRelation('user')->visible(['nickName']);
				$row->getRelation('user')->visible(['phone']);
            }*/

            $list = collection($list)->toArray();
            $c2=0;
            $c3=0;
            foreach ($list as $k => $v){
                $c2+=$v['all_money'];
                $c3+=$v['income'];
            }


            $c2 = sprintf("%01.2f", $c2);
            $c3 = sprintf("%01.2f", $c3);

            $result = array("total" => $total, "rows" => $list,"extend" => ['c1' => count($list), 'c2' => $c2, 'c3' => $c3

            ]);

            return json($result);

        }

//        print_r(Session::get("c1"));die;

        $this->assignconfig("pay_status",0);
        $this->assign("adminId",$adminId);
        return $this->view->fetch();
    }


    /**
     * 编辑 处理订单状态变更后 房源状态回归
     */
    public function doedit()
    {

        if ($this->request->isPost()) {
            $params = $this->request->post();
            $moder = model("order");
            $hmoder = model("house");

            $id = $params["row"]["id"];
            $roomid = $params["row"]["room_id"];
            $payStatus = $data["pay_status"] = $params["row"]["pay_status"];
            $data["upd_time"] = time();

            //如果是补加费用 只有是 入住的订单，并且申请了退款的 才能补差价 不加的费用会被追加到押金上 并且订单完成 无需用户在手机端退房了
            $orderinfo = $moder->where("id={$id}")->find()->toArray();

            if($orderinfo["pay_status"] == 2){
              //  $data["all_money"] = $orderinfo["all_money"] + $params["row"]["otherMoney"];
              //  $data["return_money"] = $orderinfo["return_money"] + $params["row"]["otherMoney"];
               // $data["deposit"] = $orderinfo["deposit"] + $params["row"]["otherMoney"];
              //  $data["olddeposit"] = $orderinfo["deposit"];
                $data["pay_status"] = 3 ;
                $data["refund_status"] = 1 ;

            }

            //判断是否要取消房源可预定限制 只要订单里有预定 就不能取消预定限制，除非先去订单里修改状态 房源修改状态也会根据情况 判断是否取消房源预定限制
            //这里要判断订单的所有者

            $roomId = $orderinfo["room_id"];

            //判断是否除了当前订单，是否有其他预定中的订单 如当前订单状态改变为  3 已完成 4 已取消 5 支付失败 等情况下，将可预定状态退回靠近最早的状态
            $otherOrder = db("order")->where(["pay_status"=>1,"room_id"=>$roomId])->where("id != {$id}")->order("stime asc ")->find();
            if($otherOrder){
                //计算开始时间的前两个小时
                $nowbeforeTime = $otherOrder["stime"] - 7200;
            }

            Db::startTrans();
            //处理房源状态
            // 订单状态
            // 0 未支付
            // 1 已预定（支付）
            // 2 已入住（支付）
            // 3 已完成（支付后，退房，房间回归打扫）
            // 4 已取消（未付款，未住，30分钟后，自动取消房间预定，回归空闲，或者后台管理员手动取消，前台用户不能手动取消）
            // 5 支付失败（房间回归空闲）
            // 房源状态 正常normal 使用中 using 维修 repair 打扫 cleaning 预定 reserve 隐藏 hidden
            if($payStatus ==0){
                $hdata["h_statusText"] = "normal";
            }elseif($payStatus ==1){
                //预定了未入住可以取消
                $hdata["h_statusText"] = "reserve";
            }elseif($payStatus ==2){
                //已经入住的不可以退款
                $hdata["h_statusText"] = "using";
                //$hdata["moveinto_time"] = time(); //修改入住时间（谨慎操作，因为不停的修改，时间会少，有点风险，本质上是只执行一次）风险待评估，理论上是计算出来的，这里先用计算出来的
            }elseif($payStatus ==3){
                if($otherOrder){
                    $hdata['beforeTime'] = $nowbeforeTime; //重置预定限制
                }else{
                    $hdata['beforeTime'] = Null; //取消 预定时间限制
                }
                $hdata["h_statusText"] = "cleaning";
            }elseif($payStatus ==4){
                if($otherOrder){
                    //不存在预定
                    $hdata['beforeTime'] = $nowbeforeTime; //重置预定限制
                }else{
                    $hdata['beforeTime'] = Null; //取消 预定时间限制
                }
                $hdata["h_statusText"] = "normal";

                //判断原来的订单状态的变化过程
                if($orderinfo["pay_status"] == 0){
                    //如果是未支付的订单取消直接修改状态即可
                    $data["pay_status"] = 4;
                    $data["cancel_time"] = time();
                    $data["return_money"] = $orderinfo['all_money'];
                }elseif ($orderinfo["pay_status"] == 1 && $orderinfo["refund_status"] != 3){ //只有预定未入住并且退款状态已经完成的才可以取消

                    $this->error("订单已经支付，请先申请退款，管理员可以点击 申请退款 按钮，执行退款后再执行取消操作！");

                }else{
                    //入住的 和 支付失败 和 已经取消的 和 已完成的 不做操作
                }




            }elseif($payStatus ==5){  //支付失败 如：管理员手动改成支付失败，房源就会自动回归
                if($otherOrder){
                    //不存在预定
                    $hdata['beforeTime'] = $nowbeforeTime; //重置预定限制
                }else{
                    $hdata['beforeTime'] = Null; //取消 预定时间限制
                }
                $hdata["h_statusText"] = "normal";
            }else{
                $this->error("订单状态不合法");
            }

            $hdata["updatetime"] = time();


            $r1 = $moder->where("id={$id}")->update($data);
            $r2 = $hmoder->where("id={$roomid}")->update($hdata);
            if($r1 && $r2){
                Db::commit("订单状态更新成功");

                $this->success();
            }else{
                Db::rollback();
                $this->error("订单状态更新失败");
            }



        }

    }


    //申请退款 页面 只是显示，当用户执行退款后 才进行相关数据的回退
    public function retprice(){

        $ids = $this->request->request("ids");

        if(empty($ids)){
            $this->error("订单参数错误");
        }
        $info = db("order")->where(['id'=>$ids])->find();

        if($info){
            $res2 = [];
            if($info['pay_status'] != "1"){
                $this->error("只有预定未入住的房间可以退款");
            }
            //判断是否超时扣费问题
            $time = time();
            //判断是否在允许范围内取消
            $confirm_time30 = $info["confirm_time30"];//全局免费30分钟免费取消
            $cancelpay_time =  $info["cancelpay_time"];
            //订单数据
            $updata["pay_status"] = "4";
            $updata["cancel_time"] = $time;
            $discount = 0;

            //收费
            $res = model('Config')->where("name='ordercofig'")->field("value")->find();
            if ($res) {
                $restmp = $res->toarray()["value"];
                $discount2 = json_decode($restmp, true);
                if($discount2['取消扣费比例']){
                    $discount = $discount2['取消扣费比例'];
                }

            }

            //余额支付 如果未超时 直接退回，如果超时，扣除比例 不走微信
            if($info['pay_type'] == 1){
                //超过时间，返回减少 计算收益
                if($time > $confirm_time30){
                    if($time > $cancelpay_time) {
                        if ($discount) {
                            $money = $info["totalprice"] * $discount;
                            $money = sprintf("%01.2f", $money);
                        }
                        $remoney = $info['all_money'] - $money;
                        if($remoney <0){
                            $remoney = 0;
                        }
                    }else{
                        $remoney = $info['all_money'];
                    }
                }else{
                    $remoney = $info['all_money'];
                }

                $res2['return_hour'] = 0;
                $res2['return_money'] = $remoney;
                $res2['return_wxpay'] = 0;
            }else{
                //微信支付

                if($info['pay_type'] == "0"){

                    if($time > $confirm_time30){
                        if($time > $cancelpay_time) {
                            if ($discount) {
                                $money = $info["totalprice"] * $discount;
                                $money = sprintf("%01.2f", $money);
                            }
                            $remoney = $info['all_money'] - $money;
                            if($remoney <0){
                                $remoney = 0;
                            }
                        }else{
                            $remoney = $info['all_money'];
                        }
                    }else{
                        $remoney = $info['all_money'];
                    }


                    $res2['return_hour'] = 0;
                    $res2['return_wxpay'] = $remoney;
                    $res2['return_money'] = 0;
                }else{
                    //小时卡&微信支付
                    if($time > $confirm_time30){
                        if($time > $cancelpay_time) {
                            if ($discount) {
                                $money = $info["totalprice"] * $discount;
                                $money = sprintf("%01.2f", $money);
                            }
                            $remoney = $info['all_money'] - $money;
                            if($remoney <0){
                                $remoney = 0;
                            }
                        }else{
                            $remoney = $info['all_money'];
                        }
                    }else{
                        $remoney = $info['all_money'];
                    }


                    $res2['return_wxpay'] = $remoney;
                    $res2['return_money'] = 0;
                    //计算回退的小时数
                    $user_money_log = db("user_money_log")->field("money")->where(['service_ids'=>$info['order_number']])->find();
                    $res2['return_hour'] = $user_money_log['money'];
                }

            }

            $res2['id'] = $info['id'];
            $res2['order_number'] = $info['order_number'];
            $res2['pay_type'] = $info['pay_type'];


            $this->assign("info",$res2);
            return $this->view->fetch();
        }else{
            $this->error("订单数据有误");
        }

    }

    //申请退房 页面 只是显示，当用户执行退款后 才进行相关数据的回退
    public function rethouse(){

        $ids = $this->request->request("ids");

        if(empty($ids)){
            $this->error("订单参数错误");
        }
        $info = db("order")->where(['id'=>$ids])->find();

        if($info){
            $res2 = [];
            if($info['pay_status'] != "2"){
                $this->error("只有入住的房间可以退房");
            }

            if($info['pay_type'] == "0"){
                $res2['pay_typetext'] = "微信支付";
            }elseif ($info['pay_type'] == "1"){
                $res2['pay_typetext'] = "余额支付";
            }else{
                $res2['pay_typetext'] = "小时卡%微信支付";
            }

            if($info['timing'] == "0"){
                $res2['timing'] = "全日房";
            }elseif ($info['timing'] == "1"){
                $res2['timing'] = "小时房(已选结束日期)";
            }else{
                $res2['timing'] =  "小时房(未选结束日期)";
            }
            $now = time();

            if($info['pay_type'] == 1){
                //余额支付
                //全日房 和 小时房（有结束日期） 两者情况一样
                if($info['timing'] == "0" || $info['timing'] == "1"){
                    $res2['return_money'] = 0;
                    $res2['return_wxpay'] = 0;
                    $res2['return_hour'] = 0;
                }else{
                    //小时房 无结束日期 付款时 扣除了最迟到12点的费用 和基础服务费的费用 ，所以要实时计算用户退房需要扣除的费用
                    //和用户入住计费的时间进行换算 由于程序的定时任务 会自动在12点给订单结束，所以理论上，不会超过12点，
                    $overtimeminute = $info['overtimeminute'];
                    $stime_move = $info['moveinto_time'];
                    //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                    $countday = getDatediffedaytemp($stime_move,$now);
                    $hour = 0;
                    if($countday == 1){
                        $hour = 24;
                    }
                    $counthour = getDatediffemintemp($stime_move,$now);
                    $hour2 = floor($counthour/60) + $hour;
                    $min = ($counthour - $hour2*60);
                    if($min >= $overtimeminute){
                        $hour2++;
                    }

                    //无结束日期 去最多应扣掉的小时数， 向上取整 后续根据实际情况回退 这里固定扣除一天最多10小时 配置
                    $confighour = db("config")->field("value")->where(['id'=>37])->find();
                    if($confighour && $confighour['value']){
                        $maxhour = $confighour['value'];
                    }else{
                        $maxhour = 10;
                    }
                    if($hour2 >10){
                        $hour2 = $maxhour;
                    }


                    //判断是否需要退款 如果超过了一天的费用 则按照封顶价扣费
                    $price = $info['price'];
                    $number = $info['number'];//预定房间数量
                    $allprice = $price * $hour2;//房费
                    if($allprice >= $info['totalprice']){
                        $allprice = $info['totalprice'];
                    }
                    $yfallprice = $info['all_money'] - $info['ballprice'];//已付费用（包括押金和基础服务费 基础服务费不退）
                    $retrunmoney = $yfallprice - $allprice * $number; //需要退款
                    if($retrunmoney <= 0){
                        $retrunmoney = 0;
                    }
                    $res2['return_money'] = $retrunmoney;
                    $res2['return_hour'] = 0;
                    $res2['return_wxpay'] = 0;
                }

            }elseif ($info['pay_type'] == "0"){
                //微信支付
                //全日房 和 小时房（有结束日期） 两者情况一样
                if($info['timing'] == "0" || $info['timing'] == "1"){
                    $res2['return_money'] = 0;
                    $res2['return_wxpay'] = 0;
                    $res2['return_hour'] = 0;
                }else{
                    //小时房 无结束日期 付款时 扣除了最迟到12点的费用 和基础服务费的费用 ，所以要实时计算用户退房需要扣除的费用
                    //和用户入住计费的时间进行换算 由于程序的定时任务 会自动在12点给订单结束，所以理论上，不会超过12点，
                    $overtimeminute = $info['overtimeminute'];
                    $stime_move = $info['moveinto_time'];
                    //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                    $countday = getDatediffedaytemp($stime_move,$now);
                    $hour = 0;
                    if($countday == 1){
                        $hour = 24;
                    }
                    $counthour = getDatediffemintemp($stime_move,$now);
                    $hour2 = floor($counthour/60) + $hour;
                    $min = ($counthour - $hour2*60);
                    if($min >= $overtimeminute){
                        $hour2++;
                    }


                    //无结束日期 去最多应扣掉的小时数， 向上取整 后续根据实际情况回退 这里固定扣除一天最多10小时 配置
                    $confighour = db("config")->field("value")->where(['id'=>37])->find();
                    if($confighour && $confighour['value']){
                        $maxhour = $confighour['value'];
                    }else{
                        $maxhour = 10;
                    }
                    if($hour2 >10){
                        $hour2 = $maxhour;
                    }

                    //判断是否需要退款 如果超过了一天的费用 则按照封顶价扣费
                    $price = $info['price'];
                    $number = $info['number'];//预定房间数量

                    $allprice = $price * $hour2;//房费
                    if($allprice >= $info['totalprice']){
                        $allprice = $info['totalprice'];
                    }
                    $yfallprice = $info['all_money'] - $info['ballprice'];//已付费用（包括押金和基础服务费 基础服务费不退）
                    $retrunmoney = $yfallprice - $allprice * $number;
                    if($retrunmoney <= 0){
                        $retrunmoney = 0;
                    }
                    $res2['return_money'] = $retrunmoney;
                    $res2['return_hour'] = 0;
                    $res2['return_wxpay'] = 0;

                }

            }else{
                //小时卡&微信支付 只针对小时房
                //有结束日期的 小时房 已经 付过了，主要考虑 到底使用的小时卡是否足够
                //由于支付时就扣掉了小时卡 并且计算出了 做多使用的小时卡数和需要微信支付的费用（基础服务费、部分房费），部分费用被全部记录到日志money2
                //所以这里退款根据记录的费用去掉 基础服务费后如果还大于押金 则多余的费用就是额外的房费；计算房费：money2 - ballprice - despoit
                //有结束日期，不需要押金 但基础服务费部分是必须微信付款的，所以也符合，小时卡只能抵扣房费，所以money2 就只是 基础服务费和部分房费，
                //付款时 就把这些费用计算清楚了（如果小时卡够，直接抵扣，微信只付款基础服务费；如果小时卡不够，那就是基础服务费和部分房费），所以，退房时，无需走微信支付退款。
                if($info['timing'] == "1"){
                    //小时房 有结束日期 支付时无押金
                    $res2['return_money'] = 0;
                    $res2['return_wxpay'] = 0;
                    $res2['return_hour'] = 0;



                }else{
                    $res2['return_money'] = 0;
                    //小时房 无结束日期
                    //无结束日期的小时房
                    //费用计算逻辑：预收全天的房费（即换算成对应的全天的小时卡数） + 微信费用（押金+基础服务）
                    //退款：根据实际情况 回退小时卡，如果小时卡充足，押金全退，如果不够，从押扣除，押金退回部分；
                    //如果是无结束日期的，会自动到12点，到时没有退房，程序会自动修改订单状态，发送短信，所以计算最迟以12点计算，超过了12点，只要退款押金即可
                    //小时卡数据
                    if($info['cardid']){
                        $carddata = db("user_card")->where(['id'=>$info['cardid']])->find();
                        $lesshour = $carddata["less_hours"];
                    }else{
                        $lesshour = 0;
                    }
                    //支付时写入的数据
                    $moneydata = db("user_money_log")->where(['service_ids'=>$info['order_number']])->find();
                    $overtimeminute = $info['overtimeminute'];
                    //入住计费时间
                    $stime_move = $info['moveinto_time'];

                    //自动计算的离开时间
                    $etime_move = $info['etime'];


                    //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                    $countday = getDatediffedaytemp($stime_move,$now);
                    $hour = 0;
                    if($countday == 1){
                        $hour = 24;
                    }
                    $counthour = getDatediffemintemp($stime_move,$now);
                    //实际入住的小时数
                    $hour2 = floor($counthour/60) + $hour;
                    $min = ($counthour - $hour2*60);
                    if($min >= $overtimeminute){
                        $hour2++;
                    }


                    //无结束日期 去最多应扣掉的小时数， 向上取整 后续根据实际情况回退 这里固定扣除一天最多10小时 配置
                    $confighour = db("config")->field("value")->where(['id'=>37])->find();
                    if($confighour && $confighour['value']){
                        $maxhour = $confighour['value'];
                    }else{
                        $maxhour = 10;
                    }
                    if($hour2 >10){
                        $hour2 = $maxhour;
                    }

                    //日志中的money 大于或者等于 $hour2
                    //$money2 是押金和基础服务费和部分房费
                    if($hour2 > $moneydata['money']){
                        //实时小时大于用户已经扣掉的小时数，其余部分需要微信扣款 扣款金额 单价 * ($hour2 - $moneydata['money'])
                        //退款金额 返回到 微信
                        $rm = $info['deposit'] -  $info['price'] * ($hour2-$moneydata['money']);
                        if($rm > 0){
                            $retrunmoney = $rm;
                        }else{
                            $retrunmoney = 0;
                        }

                        $res2['return_wxpay'] = $retrunmoney;
                        $res2['return_hour'] = 0;


                    }elseif ($hour2 == $moneydata['money']){
                        //已付小时数刚好抵消 押金全退
                        $retrunmoney = $info['deposit'];//已付押金
                        $res2['return_wxpay'] = $retrunmoney;
                        $res2['return_hour'] = 0;

                    }else{

                        //已付小时数 大于 实际消费的
                        //回退小时卡信息 和 押金
                        $return_hour = $moneydata['money'] - $hour2;
                        $res2['return_hour'] = $return_hour;
                        $retrunmoney = $info['deposit'];//已付押金
                        $res2['return_wxpay'] = $retrunmoney;
                    }

                }

            }


            $res2['id'] = $info['id'];
            $res2['number'] = $info['number'];
            $res2['order_number'] = $info['order_number'];
            $res2['pay_type'] = $info['pay_type'];


            $this->assign("info",$res2);
            return $this->view->fetch();
        }else{
            $this->error("订单数据有误");
        }

    }

    //处理入住房源的退房流程
    public function doreturnhouse(){
        if ($this->request->isPost()) {
            $params = $this->request->post();
            $id = $params["Oids"];
            if(empty($id)){
                $this->error("参数错误");
            }

            $odb = db("order");
            $rdb = db("house");
            $labeldb = db("label");

            Db::startTrans();
            //订单信息
            $oinfo =$odb->where(['id'=>$id])->find();

            if($oinfo){
                if($oinfo['pay_status'] != "2"){
                    $this->error("只有入住的房源可以退房");
                }

                //用户信息
                $userinfo = db("user")->where(["id"=>$oinfo['user_id']])->field("id,score,phone,nickName,money,hours")->find();
                $houseinfo = json_decode($oinfo['room_html'],true);
                //labels表 休息房、打卡房
                $labels = $houseinfo['h_lebals'];
                //酒店信息
                $hinfo = db("hotels")->where(['hid'=>$oinfo['hotelid']])->find();
                $now = time();
                //订单更新
                $orderup['upd_time'] = $now;

                //判断支付方式 余额支付 无需走微信
                if($oinfo['pay_type'] == 1){
                    //全日房 和 小时房（有结束日期） 两者情况一样
                    if($oinfo['timing'] == "0" || $oinfo['timing'] == "1"){
                        $orderup['pay_status'] = "3";//订单状态
                        $orderup['refund_status'] = 1;//退款状态 抵消费用 无需退款
                        $orderup['return_money'] = 0;// 无需退款 退款金额为0
                        $orderup['income'] = $oinfo['all_money'];//收入等于支付的金额
                        $eff1 = $odb->where(['id'=>$id])->update($orderup);
                        //回归房源状态
                        $rdata["h_statusText"] = "cleaning";
                        $rdata["updatetime"] = $now;
                        $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);
                        //修改房间属性的数量 修改label表记录
                        if($labels){
                            $number = $oinfo['number'];
                            $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                        }else{
                            $eff3 = true;
                        }

                        if($eff1 && $eff2 && $eff3){
                            Db::commit();
                            if($userinfo["phone"]){
                                //通知用户您入住的房间已经退房
                                //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                            }
                            if($hinfo["h_phone"]){
                                //通知酒店 用户已经退房，请准时打扫
                                //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                            }
                            $this->success("退房成功");
                        }else{
                            Db::rollback();
                            $this->error("退房失败，联系客服");
                        }

                    }else{
                        //小时房 无结束日期 付款时 扣除了最迟到12点的费用 和基础服务费的费用 ，所以要实时计算用户退房需要扣除的费用
                        //和用户入住计费的时间进行换算 由于程序的定时任务 会自动在12点给订单结束，所以理论上，不会超过12点，
                        $overtimeminute = $oinfo['overtimeminute'];
                        $stime_move = $oinfo['moveinto_time'];
                        //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                        $countday = getDatediffedaytemp($stime_move,$now);
                        $hour = 0;
                        if($countday == 1){
                            $hour = 24;
                        }
                        $counthour = getDatediffemintemp($stime_move,$now);
                        $hour2 = floor($counthour/60) + $hour;
                        $min = ($counthour - $hour2*60);
                        if($min >= $overtimeminute){
                            $hour2++;
                        }


                        //无结束日期 去最多应扣掉的小时数， 向上取整 后续根据实际情况回退 这里固定扣除一天最多10小时 配置
                        $confighour = db("config")->field("value")->where(['id'=>37])->find();
                        if($confighour && $confighour['value']){
                            $maxhour = $confighour['value'];
                        }else{
                            $maxhour = 10;
                        }
                        if($hour2 >10){
                            $hour2 = $maxhour;
                        }

                        //判断是否需要退款 如果超过了一天的费用 则按照封顶价扣费
                        $price = $oinfo['price'];
                        $number = $oinfo['number'];//预定房间数量

                        $allprice = $price * $hour2;//房费
                        if($allprice >= $oinfo['totalprice']){
                            $allprice = $oinfo['totalprice'];
                        }
                        $yfallprice = $oinfo['all_money'] - $oinfo['ballprice'];//已付费用（包括押金和基础服务费 基础服务费不退）
                        $retrunmoney = $yfallprice - $allprice * $number;

                        $orderup['pay_status'] = "3";//订单状态
                        $orderup['all_price'] = $allprice * $number;//实际房费
                        $orderup['refund_status'] = 3;//退款状态 抵消费用 无需退款
                        $orderup['return_money'] = $retrunmoney;// 无需退款 动态计算房费
                        $orderup['income'] = $oinfo['all_money'] - $retrunmoney;//收入等于支付的金额
                        $eff1 = $odb->where(['id'=>$id])->update($orderup);
                        //如果退款大于0 则 写入余额退款日志
                        if($retrunmoney > 0){
                            //余额支付 追加 退款 日志
                            $moneylog['createtime'] = $now;
                            $moneylog['type'] = 1;
                            $moneylog['user_id'] = $oinfo['user_id'];
                            $moneylog['memo'] = "余额付款-".$hinfo['hoteltitle'];
                            $moneylog['service_ids'] = $oinfo['order_number'];
                            $moneylog['money'] = $retrunmoney;
                            $moneylog['type2'] = 1;
                            $moneylog['before'] = $userinfo['money'];
                            $moneylog['after'] =  $userinfo['money'] + $retrunmoney;
                            //添加消费日志
                            $eff2 = db("user_money_log")->insert($moneylog);
                        }else{
                            $eff2 = true;
                        }
                        //修改用户余额 user表
                        $userup['money'] = $userinfo['money'] + $retrunmoney;
                        $userup['updatetime'] = $now;
                        $eff3 = db("user")->where(["id"=>$oinfo['user_id']])->update($userup);

                        //回归房源状态
                        $rdata["h_statusText"] = "cleaning";
                        $rdata["updatetime"] = $now;
                        $eff4 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                        //修改房间属性的数量 修改label表记录
                        if($labels){
                            $number = $oinfo['number'];
                            $eff5 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                        }else{
                            $eff5 = true;
                        }

                        if($eff1 && $eff2 && $eff3 && $eff4 && $eff5){
                            Db::commit();
                            if($userinfo["phone"]){
                                //通知用户您入住的房间已经退房
                                //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                            }
                            if($hinfo["h_phone"]){
                                //通知酒店 用户已经退房，请准时打扫
                                //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                            }
                            $this->success("退房成功");
                        }else{
                            Db::rollback();
                            $this->error("退房失败，联系客服");
                        }


                    }


                }else{
                    //微信支付
                    if($oinfo['pay_type'] == "0"){
                        //全日房 和 小时房（有结束日期） 两者情况一样
                        if($oinfo['timing'] == "0" || $oinfo['timing'] == "1"){
                            //微信支付
                            //全日房 支付时 押金和基础服务费和房费都已经付款
                            //退房时 只要修改订单状态就行 无需退款
                            $orderup['pay_status'] = "3";//订单状态
                            $orderup['refund_status'] = 1;//退款状态 抵消费用 无需退款
                            $orderup['return_money'] = 0;// 无需退款 退款金额为0
                            $orderup['income'] = $oinfo['all_money'];//收入等于支付的金额
                            $eff1 = $odb->where(['id'=>$id])->update($orderup);
                            //回归房源状态
                            $rdata["h_statusText"] = "cleaning";
                            $rdata["updatetime"] = $now;
                            $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);
                            //修改房间属性的数量 修改label表记录
                            if($labels){
                                $number = $oinfo['number'];
                                $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                            }else{
                                $eff3 = true;
                            }

                            if($eff1 && $eff2 && $eff3){
                                Db::commit();
                                if($userinfo["phone"]){
                                    //通知用户您入住的房间已经退房
                                    //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                                }
                                if($hinfo["h_phone"]){
                                    //通知酒店 用户已经退房，请准时打扫
                                    //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                                }
                                $this->success("退房成功");
                            }else{
                                Db::rollback();
                                $this->error("退房失败，联系客服");
                            }

                        }else{
                            //小时房 无结束日期 付款时 扣除了最迟到12点的费用 和基础服务费的费用 ，所以要实时计算用户退房需要扣除的费用
                            //和用户入住计费的时间进行换算 由于程序的定时任务 会自动在12点给订单结束，所以理论上，不会超过12点，
                            $overtimeminute = $oinfo['overtimeminute'];
                            $stime_move = $oinfo['moveinto_time'];
                            //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                            $countday = getDatediffedaytemp($stime_move,$now);
                            $hour = 0;
                            if($countday == 1){
                                $hour = 24;
                            }
                            $counthour = getDatediffemintemp($stime_move,$now);
                            $hour2 = floor($counthour/60) + $hour;
                            $min = ($counthour - $hour2*60);
                            if($min >= $overtimeminute){
                                $hour2++;
                            }


                            //无结束日期 去最多应扣掉的小时数， 向上取整 后续根据实际情况回退 这里固定扣除一天最多10小时 配置
                            $confighour = db("config")->field("value")->where(['id'=>37])->find();
                            if($confighour && $confighour['value']){
                                $maxhour = $confighour['value'];
                            }else{
                                $maxhour = 10;
                            }
                            if($hour2 >10){
                                $hour2 = $maxhour;
                            }

                            //判断是否需要退款 如果超过了一天的费用 则按照封顶价扣费
                            $price = $oinfo['price'];
                            $number = $oinfo['number'];//预定房间数量

                            $allprice = $price * $hour2;//房费
                            if($allprice >= $oinfo['totalprice']){
                                $allprice = $oinfo['totalprice'];
                            }
                            $yfallprice = $oinfo['all_money'] - $oinfo['ballprice'];//已付费用（包括押金和基础服务费 基础服务费不退）
                            $retrunmoney = $yfallprice - $allprice * $number;
                            $orderup['all_price'] = $allprice * $number;//实际房费
                            $orderup['pay_status'] = "3";//订单状态
                            $orderup['return_money'] = $retrunmoney;// 无需退款 动态计算房费
                            $orderup['income'] = $oinfo['all_money'] - $retrunmoney;//收入等于支付的金额
                            //如果退款大于0 则 写入余额退款日志
                            if($retrunmoney > 0){
                                $orderup['refund_status'] = 2;//退款状态 申请退款中  等微信退款完成后 改变状态为 3
                                $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                                $orderup['refund_number'] = $refund_number;
                                //余额支付 追加 退款 日志
                                $moneylog['createtime'] = $now;
                                $moneylog['type'] = 1;
                                $moneylog['user_id'] = $oinfo['user_id'];
                                $moneylog['memo'] = "余额付款-".$hinfo['hoteltitle'];
                                $moneylog['service_ids'] = $oinfo['order_number'];
                                $moneylog['money'] = $retrunmoney;
                                $moneylog['type2'] = 1;
                                $moneylog['before'] = $userinfo['money'];
                                $moneylog['after'] =  $userinfo['money'] + $retrunmoney;
                                //添加消费日志
                                $eff2 = db("user_money_log")->insert($moneylog);
                                //走微信退款流程
                                //通过微信api进行退款流程

                                $nonce_str = WxPay::str_rand();//随机32位字符串
                                $total_fee = $oinfo['all_money'] * 100;//总金额，单位：分
                                //$total_fee= 0.01 * 100;//测试 一分钱
                                $refund_fee = $retrunmoney * 100;//退款金额，单位：分
                                //$refund_fee= 0.01 * 100;//测试 一分钱
                                $parma = array(
                                    'appid'=> WxPay::appid,
                                    'mch_id'=> WxPay::mch_id,
                                    'nonce_str'=> $nonce_str,
                                    'out_trade_no'=> $oinfo['order_number'],//小程序自定义订单号，支付时后台生成
                                    'out_refund_no'=> $refund_number,
                                    'refund_fee'=> $refund_fee,
                                    'total_fee'=> $total_fee,
                                    'transaction_id' => $oinfo['transaction_id'],//小程序平台订单号，微信平台生成
                                );

                                $KEY = WxPay::key;//小程序支付秘钥
                                $parma['sign'] = $this->getSign($parma, $KEY);
                                $post_xml = $this->arrayToXml($parma);//把参数转化成xml格式
                                //向微信平台api发送退款参数
                                $xmlresult = $this->postXmlSSLCurl($post_xml,'https://api.mch.weixin.qq.com/secapi/pay/refund');
                                $array = $this->xml2array($xmlresult);
                                //两个success表示退款成功，无需使用回调，在此进行逻辑处理即可
                                if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
                                    $orderup["refund_status"] = 3;

                                }else{
                                    $orderup["refund_status"] = 4;
                                    $this->error("退款失败");
                                }


                            }else{
                                $eff2 = true;
                                $orderup['refund_status'] = 3;//退款状态 抵消费用 无需退款
                            }

                            $eff1 = $odb->where(['id'=>$id])->update($orderup);
                            //修改用户余额 user表
                            $userup['money'] = $userinfo['money'] + $retrunmoney;
                            $userup['updatetime'] = $now;
                            $eff3 = db("user")->where(["id"=>$oinfo['user_id']])->update($userup);
                            //回归房源状态
                            $rdata["h_statusText"] = "cleaning";
                            $rdata["updatetime"] = $now;
                            $eff4 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);
                            //修改房间属性的数量 修改label表记录
                            if($labels){
                                $number = $oinfo['number'];
                                $eff5 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                            }else{
                                $eff5 = true;
                            }

                            if($eff1 && $eff2 && $eff3 && $eff4 && $eff5){
                                Db::commit();
                                if($userinfo["phone"]){
                                    //通知用户您入住的房间已经退房
                                    //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                                }
                                if($hinfo["h_phone"]){
                                    //通知酒店 用户已经退房，请准时打扫
                                    //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                                }
                                if($retrunmoney > 0){
                                    $this->success("退房成功,退款成功，请核实");
                                }else{
                                    $this->success("退房成功,费用抵扣，无需退款");
                                }



                            }else{
                                Db::rollback();
                                $this->error("退房失败，联系客服");
                            }

                        }


                    }else{

                        //小时卡&微信支付 只针对小时房
                        //有结束日期的 小时房 已经 付过了，主要考虑 到底使用的小时卡是否足够
                        //由于支付时就扣掉了小时卡 并且计算出了 做多使用的小时卡数和需要微信支付的费用（基础服务费、部分房费），部分费用被全部记录到日志money2
                        //所以这里退款根据记录的费用去掉 基础服务费后如果还大于押金 则多余的费用就是额外的房费；计算房费：money2 - ballprice - despoit
                        //有结束日期，不需要押金 但基础服务费部分是必须微信付款的，所以也符合，小时卡只能抵扣房费，所以money2 就只是 基础服务费和部分房费，
                        //付款时 就把这些费用计算清楚了（如果小时卡够，直接抵扣，微信只付款基础服务费；如果小时卡不够，那就是基础服务费和部分房费），所以，退房时，无需走微信支付退款。

                        if($oinfo['timing'] == "0"){
                            $this->error("全日房不能小时卡支付");
                        }

                        if($oinfo['timing'] == "1"){

                            //微信支付 小时房 有结束日期
                            //全日房 支付时 押金和基础服务费和房费都已经付款
                            //退房时 只要修改订单状态就行 无需退款
                            $orderup['pay_status'] = "3";//订单状态
                            $orderup['refund_status'] = 1;//退款状态 抵消费用 无需退款
                            $orderup['return_money'] = 0;// 无需退款 退款金额为0
                            $orderup['income'] = $oinfo['all_money'];//all_money 是微信需要支付的款；  收入= 已付的微信款

                            $eff1 = $odb->where(['id'=>$id])->update($orderup);
                            //回归房源状态
                            $rdata["h_statusText"] = "cleaning";
                            $rdata["updatetime"] = $now;
                            $eff2 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                            //修改房间属性的数量 修改label表记录
                            if($labels){
                                $number = $oinfo['number'];
                                $eff3 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                            }else{
                                $eff3 = true;
                            }
                            if($eff1 && $eff2 && $eff3){
                                Db::commit();
                                if($userinfo["phone"]){
                                    //通知用户您入住的房间已经退房
                                    //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                                }
                                if($hinfo["h_phone"]){
                                    //通知酒店 用户已经退房，请准时打扫
                                    //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                                }
                                $this->success("退房成功");
                            }else{
                                Db::rollback();
                                $this->error("退房失败，联系客服");
                            }

                        }else{
                            //无结束日期的小时房
                            //费用计算逻辑：预收全天的房费（即换算成对应的全天的小时卡数） + 微信费用（押金+基础服务）
                            //退款：根据实际情况 回退小时卡，如果小时卡充足，押金全退，如果不够，从押扣除，押金退回部分；
                            //如果是无结束日期的，会自动到12点，到时没有退房，程序会自动修改订单状态，发送短信，所以计算最迟以12点计算，超过了12点，只要退款押金即可
                            //小时卡数据
                            if($oinfo['cardid']){
                                $carddata = db("user_card")->where(['id'=>$oinfo['cardid']])->find();
                                $lesshour = $carddata["less_hours"];
                            }else{
                                $lesshour = 0;
                            }
                            //支付时写入的数据
                            $moneydata = db("user_money_log")->where(['service_ids'=>$oinfo['order_number']])->find();

                            $overtimeminute = $oinfo['overtimeminute'];
                            //入住计费时间
                            $stime_move = $oinfo['moveinto_time'];

                            //自动计算的离开时间
                            $etime_move = $oinfo['etime'];
                            $moneylog['createtime'] = $now;
                            $moneylog['user_id'] = $oinfo['user_id'];
                            $moneylog['memo'] = "小时卡&微信支付-".$hinfo['hoteltitle'];
                            $moneylog['service_ids'] = $oinfo['order_number'];
                            //总之 无结束日期的小时房 最多不会超过 30个小时 如果就是超过了30小时 也按照 30小时计算
                            $countday = getDatediffedaytemp($stime_move,$now);
                            $hour = 0;
                            if($countday == 1){
                                $hour = 24;
                            }

                            $counthour = getDatediffemintemp($stime_move,$now);
                            //实际入住的小时数
                            $hour2 = floor($counthour/60) + $hour;
                            $min = ($counthour - $hour2*60);
                            if($min >= $overtimeminute){
                                $hour2++;
                            }

                            //无结束日期 去最多应扣掉的小时数， 向上取整 后续根据实际情况回退 这里固定扣除一天最多10小时 配置
                            $confighour = db("config")->field("value")->where(['id'=>37])->find();
                            if($confighour && $confighour['value']){
                                $maxhour = $confighour['value'];
                            }else{
                                $maxhour = 10;
                            }
                            if($hour2 >10){
                                $hour2 = $maxhour;
                            }

                            //日志中的money 大于或者等于 $hour2
                            //$money2 是押金和基础服务费和部分房费
                            if($hour2 > $moneydata['money']){
                                $returnhourflag = false;
                                $returnhour = 0;
                                //实时小时大于用户已经扣掉的小时数，其余部分需要微信扣款 扣款金额 单价 * ($hour2 - $moneydata['money'])
                                //退款金额 返回到 微信
                                $rm = $oinfo['deposit'] -  $oinfo['price'] * ($hour2-$moneydata['money']);
                                if($rm > 0){
                                    $retrunmoney = $rm;
                                }else{
                                    $retrunmoney = 0;
                                }

                                $moneylog['money'] = 0;//小时卡回退0小时
                                $moneylog['money2'] = $retrunmoney;
                                $moneylog['type'] = 2;
                                $moneylog['type2'] = 1;
                                $moneylog['before'] = 0;
                                $moneylog['after'] =  0;
                                $eff1 = true;
                                //房费
                                $orderup['all_price'] = $oinfo['price'] * $hour2 * $oinfo['number'];//实际房费
                                //收入
                                $orderup['income'] = $orderup['all_price'] + $oinfo['ballprice'];//收入等于房费+基础服务费

                            }elseif ($hour2 == $moneydata['money']){
                                $returnhourflag = false;
                                $returnhour = 0;
                                //已付小时数刚好抵消 押金全退
                                $retrunmoney = $oinfo['deposit'];//已付押金
                                $moneylog['money'] = 0;//小时卡回退0小时
                                $moneylog['money2'] = $retrunmoney;
                                $moneylog['type'] = 2;
                                $moneylog['type2'] = 1;
                                $moneylog['before'] = 0;
                                $moneylog['after'] =  0;
                                $eff1 = true;
                                //房费
                                $orderup['all_price'] = $oinfo['price'] * $hour2 * $oinfo['number'];//实际房费
                                //收入
                                $orderup['income'] = $orderup['all_price'] + $oinfo['ballprice'];//收入等于房费+基础服务费

                            }else{
                                $returnhourflag = true;
                                //已付小时数 大于 实际消费的
                                //回退小时卡信息 和 押金
                                $return_hour = $moneydata['money'] - $hour2;
                                $returnhour = $return_hour;
                                $retrunmoney = $oinfo['deposit'];//已付押金

                                $moneylog['money'] = $return_hour;//小时卡回退0小时
                                $moneylog['money2'] = $retrunmoney;
                                $moneylog['type'] = 2;
                                $moneylog['type2'] = 1;
                                $moneylog['before'] = $carddata['less_hours'];
                                $moneylog['after'] =  $carddata['less_hours'] + $return_hour;

                                $cardup['updatetime'] = $now;
                                $cardup['status'] = 1;
                                $cardup['less_hours'] = $carddata['less_hours'] + $return_hour;
                                $eff1 = db("user_card")->where(['id'=>$carddata['id']])->update($cardup);

                                //房费
                                $orderup['all_price'] = $oinfo['price'] * $hour2 * $oinfo['number'];//实际房费
                                //收入
                                $orderup['income'] = $orderup['all_price'] + $oinfo['ballprice'];//收入等于房费+基础服务费
                            }

                            //添加消费日志
                            $eff2 = db("user_money_log")->insert($moneylog);
                            $orderup['pay_status'] = "3";//订单状态
                            $orderup['return_money'] = $retrunmoney;// 退款金额

                            if($retrunmoney > 0){

                                //走微信退款
                                $orderup['refund_status'] = 2;//退款状态 申请退款中  等微信退款完成后 改变状态为 3
                                $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                                $orderup['refund_number'] = $refund_number;

                                //走微信退款流程
                                //通过微信api进行退款流程

                                $nonce_str = WxPay::str_rand();//随机32位字符串
                                $total_fee = $oinfo['all_money'] * 100;//总金额，单位：分
                                //$total_fee= 0.01 * 100;//测试 一分钱
                                $refund_fee = $retrunmoney * 100;//退款金额，单位：分
                                //$refund_fee= 0.01 * 100;//测试 一分钱
                                $parma = array(
                                    'appid'=> WxPay::appid,
                                    'mch_id'=> WxPay::mch_id,
                                    'nonce_str'=> $nonce_str,
                                    'out_trade_no'=> $oinfo['order_number'],//小程序自定义订单号，支付时后台生成
                                    'out_refund_no'=> $refund_number,
                                    'refund_fee'=> $refund_fee,
                                    'total_fee'=> $total_fee,
                                    'transaction_id' => $oinfo['transaction_id'],//小程序平台订单号，微信平台生成
                                );

                                $KEY = WxPay::key;//小程序支付秘钥
                                $parma['sign'] = $this->getSign($parma, $KEY);
                                $post_xml = $this->arrayToXml($parma);//把参数转化成xml格式
                                //向微信平台api发送退款参数
                                $xmlresult = $this->postXmlSSLCurl($post_xml,'https://api.mch.weixin.qq.com/secapi/pay/refund');
                                $array = $this->xml2array($xmlresult);
                                //两个success表示退款成功，无需使用回调，在此进行逻辑处理即可
                                if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
                                    $orderup["refund_status"] = 3;

                                }else{
                                    $orderup["refund_status"] = 4;
                                    $this->error("退款失败");
                                }
                                $eff3 = $odb->where(['id'=>$id])->update($orderup);

                                if($returnhourflag){
                                    //修改用户小时卡 user表
                                    $userup['hours'] = $userinfo['hours'] + $returnhour;
                                    $userup['updatetime'] = $now;
                                    $eff4 = db("user")->where(["id"=>$oinfo['user_id']])->update($userup);
                                }else{
                                    $eff4 = true;
                                }

                                //回归房源状态
                                $rdata["h_statusText"] = "cleaning";
                                $rdata["updatetime"] = $now;
                                $eff5 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                                //修改房间属性的数量 修改label表记录
                                if($labels){
                                    $number = $oinfo['number'];
                                    $eff6 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                                }else{
                                    $eff6 = true;
                                }
                                if($eff1 && $eff2 && $eff3 && $eff4 && $eff5 && $eff6){
                                    Db::commit();
                                    if($userinfo["phone"]){
                                        //通知用户您入住的房间已经退房
                                        //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                                    }
                                    if($hinfo["h_phone"]){
                                        //通知酒店 用户已经退房，请准时打扫
                                        //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                                    }

                                    $this->success("退房成功,退款成功，请核实");


                                }else{
                                    Db::rollback();
                                    $this->error("退房失败，联系客服");
                                }


                            }else{
                                //不走微信
                                $orderup['refund_status'] = 3;//自动完成

                                $eff3 = $odb->where(['id'=>$id])->update($orderup);

                                if($returnhourflag){
                                    //修改用户小时卡 user表
                                    $userup['hours'] = $userinfo['hours'] + $returnhour;
                                    $userup['updatetime'] = $now;
                                    $eff4 = db("user")->where(["id"=>$oinfo['user_id']])->update($userup);
                                }else{
                                    $eff4 = true;
                                }

                                //回归房源状态
                                $rdata["h_statusText"] = "cleaning";
                                $rdata["updatetime"] = $now;
                                $eff5 = $rdb->where("id={$oinfo['room_id']}")->update($rdata);

                                //修改房间属性的数量 修改label表记录
                                if($labels){
                                    $number = $oinfo['number'];
                                    $eff6 = $labeldb->execute("UPDATE `fa_label` SET `lcount`=`lcount` + $number,`updtime`= $now WHERE  `id` in ($labels) ");
                                }else{
                                    $eff6 = true;
                                }
                                if($eff1 && $eff2 && $eff3 && $eff4 && $eff5 && $eff6){
                                    Db::commit();
                                    if($userinfo["phone"]){
                                        //通知用户您入住的房间已经退房
                                        //sendCmsg($userinfo["phone"],$houseinfo['h_title']);
                                    }
                                    if($hinfo["h_phone"]){
                                        //通知酒店 用户已经退房，请准时打扫
                                        //sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                                    }
                                    $this->success("退房成功,费用抵扣，无需退款");


                                }else{
                                    Db::rollback();
                                    $this->error("退房失败，联系客服");
                                }
                            }




                        }





                    }
                }


            }else{
                $this->error("订单信息有误");
            }




        }
    }


    //处理批量申请退款 只有 已经预定(付款的),且没有入住的才可以在后台申请，已经入住的不可以退款
    public function applymoney(){
        if ($this->request->isPost()) {

            try{

                $params = $this->request->post();
                $ids = $params["Oids"];

                $updata["refund_status"] = 2;
                $updata["upd_time"] = time();

                $olist = db("order")->field("id,order_number,pay_status,all_money,refund_status,refund_number")->where(["pay_status"=>1,"refund_status"=>0])->where("id", 'in', $ids)->select();

                if($olist){
                    foreach ($olist as $v){
                        $refund_number = "refund_".$v['id'].date("YmdHis", time()) . rand(10000000, 99999999);
                        $updata["refund_number"] = $refund_number;
                        $updata["return_money"] = $v["all_money"]; //退款金额等于总付款金额

                        db("order")->where(["id"=>$v["id"]])->update($updata);
                    }

                    $this->success("申请退款成功，请执行退款");

                }else{
                    $this->error("没有找到需要退款的订单");
                }

            }catch (\think\exception\PDOException $e){

                $this->error($e->getMessage());
            }

        }


    }


    //批量执行退款 处理
    public function doreturnprice(){
        if ($this->request->isPost()) {
            $params = $this->request->post();
            $id = $params["Oids"];
            if(empty($id)){
                $this->error("参数错误");
            }

            //获取订单信息
            $info = db("order")->where(['id'=>$id])->find();
            if($info){
                if($info['pay_status'] != "1"){
                    $this->error("只有预定未入住的房间可以退款");
                }
                //酒店信息
                $hinfo = db("hotels")->where(['hid'=>$info['hotelid']])->field("hid,hoteltitle")->find();
                //房间数据
                $rinfo = db("house")->field("id,h_stock,h_sell")->where(['id'=>$info['room_id']])->find();

                //获取用户信息
                $userinfo = db("user")->where(['id'=>$info['user_id']])->find();

                Db::startTrans();

                //判断是否在允许范围内取消
                $cancelpay_time =  $info["cancelpay_time"];
                $time = time();
                //订单数据 申请退款 也是 取消订单的一种，所以状态改为 已取消
                $updata["pay_status"] = "4";
                $updata["cancel_time"] = $time;
                $discount = 0;

                //收费
                $res = model('Config')->where("name='discount'")->field("value")->find();
                if ($res) {
                    $restmp = $res->toarray()["value"];
                    $discount = json_decode($restmp, true);
                }
                //房源数据回归 销量 库存 是否预定
                $rnumber = $rinfo['h_stock'];//库存 历史
                $snumber = $rinfo['h_sell'];//销量 历史 回调是改变
               // $houseup['h_stock'] = $rnumber + $info['number']; //库存 新
                $houseup['updatetime'] = $time;
                $houseup['h_sell'] = $snumber + $info['number']; //销量 新

                //判断是否改变预定标识
                $count = db("order")->where(['room_id'=>$rinfo['id'],"pay_status"=>"1"])->count();
                if($count == 0){
                    $houseup['h_reserve'] = 0;//房间预定标识
                }
                //更新房间数据
                $eff1 = db("house")->where(['id'=>$rinfo['id']])->update($houseup);

                //余额支付 如果未超时 直接退回，如果超时，扣除比例 不走微信
                if($info['pay_type'] == 1){

                    //余额支付 回退余额 追加 日志
                    $moneylog['createtime'] = $time;
                    $moneylog['type'] = 1;
                    $moneylog['type2'] = 1;//退回
                    $moneylog['user_id'] = $info['user_id'];
                    $moneylog['memo'] = "余额支付-".$hinfo['hoteltitle'];
                    $moneylog['service_ids'] = $info['order_number'];

                    if($time > $cancelpay_time) {
                        if ($discount) {
                            $money = $info["totalprice"] * $discount;
                            $money = sprintf("%01.2f", $money);
                        }
                        $remoney = $info['all_money'] - $money;
                        if($remoney <0){
                            $remoney = 0;
                        }
                        $moneylog['after'] =  $userinfo['money'] + $remoney;
                        $moneylog['money'] = sprintf("%01.2f", $remoney);
                        $moneylog['remark'] = "支付金额".$info['all_money']."元，超时取消，扣除费用".$money."元";

                        $updata['return_money'] = $remoney;//退款金额
                        $updata['income'] = $money;//扣除的费用就是收入

                    }else{
                        $updata['return_money'] = $info['all_money'];//退款金额
                        $moneylog['after'] =  $userinfo['money'] + $info['all_money'];
                        $moneylog['money'] = sprintf("%01.2f", $info['all_money']);
                        $updata['income'] = 0;//收入为0
                    }
                    $moneylog['before'] = $userinfo['money'];

                    //添加消费日志
                    $eff2 = db("user_money_log")->insert($moneylog);
                    //修改账户余额 余额
                    $usermoney["money"] = $moneylog['after'];
                    $usermoney['updatetime'] = time();
                    $eff3 = db("user")->where(['id'=>$info['user_id']])->update($usermoney);

                    //更新订单数据
                    //余额支付 自动退款成功
                    $updata["refund_status"] = 3;//已退款
                    $eff4 = db("order")->where("id={$info['id']}")->update($updata);


                    if($eff1 && $eff2 && $eff3 && $eff4){
                        //执行退款后发送短信
                        //发送酒店
                        if($info["h_phone"] && $info["user_name"]){
                            sendmsgHCancel($info["h_phone"],$info["user_name"],$money);
                        }
                        //发送给用户
                        if($info["user_phone"] && $info["h_phone"]){
                            sendmsgUCancel($info["user_phone"],$money,$info["h_phone"]);
                        }

                        Db::commit();
                        $this->success("退款成功，请核实");
                    }else{
                        Db::rollback();
                        $this->error("订单退款失败");
                    }



                }else{
                    //微信支付
                    $moneylog['type'] = 0;
                    $moneylog['type2'] = 1;
                    //微信支付 和 小时卡支付（微信支付） 走微信退款
                    $remoney = 0;//微信退款金额
                    if($info['pay_type'] == "0"){
                        //微信支付 回退 追加 日志
                        $moneylog['createtime'] = $time;
                        $moneylog['user_id'] = $info['user_id'];
                        $moneylog['memo'] = "微信支付-".$hinfo['hoteltitle'];
                        $moneylog['service_ids'] = $info['order_number'];

                        //超过时间，返回减少
                        if($time > $cancelpay_time) {
                            if ($discount) {
                                $money = $info["totalprice"] * $discount;
                                $money = sprintf("%01.2f", $money);
                            }
                            $remoney = $info['all_money'] - $money;
                            if($remoney <0){
                                $remoney = 0;
                            }
                           // $moneylog['after'] =  $userinfo['money'] + $remoney; 微信支付 不用考虑
                            $moneylog['money'] = sprintf("%01.2f", $remoney);
                            $moneylog['remark'] = "支付金额".$info['all_money']."元，超时取消，扣除费用".$money."元";
                            $updata['income'] = $money;
                            $updata['return_money'] = $remoney;//退款金额
                        }else{
                            $remoney = $info['all_money'];
                          //  $moneylog['after'] =  $userinfo['money'] + $info['all_money']; 微信支付 不用考虑
                            $moneylog['money'] = sprintf("%01.2f", $info['all_money']);
                            $updata['income'] = 0;
                            $updata['return_money'] = $info['all_money'];//退款金额
                        }

                      //  $moneylog['before'] = $userinfo['money']; 微信支付 不用考虑

                        //添加消费日志
                        $eff2 = db("user_money_log")->insert($moneylog);
                        $eff3 = true;

                        //准备退款数据
                        //执行退款
                        $updata["upd_time"] = $time;
                        $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                        $updata["refund_number"] = $refund_number;



                        //如果退款金额 大于0 则走微信退款
                        if($remoney > 0){
                            $updata["refund_status"] = 2;//申请退款中
                            //更新订单数据
                            $eff4 = db("order")->where("id={$info['id']}")->update($updata);
                            $refundRes = $this->submitDrawBack($info["all_money"],$remoney ,$info["order_number"],$refund_number,$info["transaction_id"],$info['user_id']);
                            file_put_contents("refundadmin.json",var_export($refundRes,true).PHP_EOL,FILE_APPEND);

                            //#todo 这里理论上还应该考虑 退款后 积分回退的逻辑，暂时先不考虑
                            if ($refundRes['RETURN_CODE'] == 'SUCCESS' && $refundRes['RESULT_CODE'] == 'SUCCESS') {
                                file_put_contents("refundadminsuc.json",var_export($refundRes,true));
                                //退款成功 修改订单状态
                                $updata2["refund_status"] = 3;
                                $updata2["pay_status"] = "4";//已经取消
                                $updata2["upd_time"] = time();
                                $eff5 = db("order")->where(["id"=>$info["id"]])->update($updata2);

                                if($eff1 && $eff2 && $eff3 && $eff4 && $eff5){
                                    //取消成功后发送短信
                                    //发送酒店
                                    if($info["h_phone"] && $info["user_name"]){
                                        sendmsgHCancel($info["h_phone"],$info["user_name"],$money);
                                    }
                                    //发送给用户
                                    if($info["user_phone"] && $info["h_phone"]){
                                        sendmsgUCancel($info["user_phone"],$money,$info["h_phone"]);
                                    }

                                    Db::commit();
                                    $this->success("订单取消成功,退款成功，请核实");
                                }else{
                                    Db::rollback();
                                    $this->error("订单取消失败");
                                }

                            }else{
                                file_put_contents("refundadminerr.json",var_export($refundRes,true).PHP_EOL,FILE_APPEND);
                                $msg = "退款失败";
                                Db::rollback();
                                $this->error($msg);
                            }


                        }else{
                            $updata["refund_status"] = 1;//抵消 不走退款
                            //更新订单数据
                            $eff4 =db("order")->where("id={$info['id']}")->update($updata);

                            if($eff1 && $eff2 && $eff3 && $eff4){
                                //取消成功后发送短信
                                //发送酒店
                                if($info["h_phone"] && $info["user_name"]){
                                    sendmsgHCancel($info["h_phone"],$info["user_name"],$money);
                                }
                                //发送给用户
                                if($info["user_phone"] && $info["h_phone"]){
                                    sendmsgUCancel($info["user_phone"],$money,$info["h_phone"]);
                                }

                                Db::commit();
                                $this->success("订单取消成功，支付的金额刚好抵扣超时取消，无需退款");
                            }else{
                                Db::rollback();
                                $this->error("订单取消失败");
                            }

                        }


                    }else{
                        //小时卡&微信支付
                        $moneylog['type'] = 2;
                        $moneylog['type2'] = 1;
                        //小时卡支付（微信支付） 小时卡退回 微信扣费
                        //小时卡+微信支付 回退 追加 日志
                        $moneylog['createtime'] = $time;
                        $moneylog['user_id'] = $info['user_id'];
                        $moneylog['memo'] = "小时卡&微信支付-".$hinfo['hoteltitle'];
                        $moneylog['service_ids'] = $info['order_number'];
                        //消费记录表
                        $usermoneydata = db("user_money_log")->where(['user_id'=>$info['user_id'],'service_ids'=>$info['order_number']])->find();

                        //用户小时卡表 使用了小时卡
                        if($info['cardid']){
                            $usercarddata = db("user_card")->where(['id'=>$info['cardid']])->find();
                            $less_hours = $usercarddata['less_hours']; //old
                            $ucdataup['less_hours'] = $usermoneydata['money'] + $less_hours; //new
                            $ucdataup['updatetime'] = $time;
                            $ucdataup['status'] = 1;//修改为 未使用完状态
                            $eff2 = db("user_card")->where(['id'=>$info['cardid']])->update($ucdataup);

                            $moneylog['after'] = $usermoneydata['before'] + $usermoneydata['money'];
                            $moneylog['before'] = $usermoneydata['before'];
                            $moneylog['money'] = $usermoneydata['money'];

                        }else{
                            //未使用，虽然用户选择了，但是可能支付时候，没有了小时数
                            $eff2 = true;
                            $moneylog['after'] = $usermoneydata['before'];
                            $moneylog['before'] = $usermoneydata['before'];
                        }

                        //超过时间，返回减少 扣除微信支付的金额
                        if($time > $cancelpay_time) {
                            if ($discount) {
                                $money = $usermoneydata["money2"] * $discount;
                                $money = sprintf("%01.2f", $money);
                            }
                            $remoney = $usermoneydata["money2"] - $money;
                            if($remoney <0){
                                $remoney = 0;
                            }

                            $moneylog['money2'] = "+".sprintf("%01.2f", $remoney);
                            $moneylog['remark'] = "微信支付金额".$usermoneydata["money2"]."元，超时取消，小时数正常返回，扣除微信付款部分费用".$money."元";
                            $updata['income'] = $money;
                            $updata['return_money'] = $remoney;//退款金额

                        }else{
                            $remoney = $info['all_money'];
                            $moneylog['money2'] = sprintf("%01.2f", $info['all_money']);
                            $moneylog['remark'] = "微信支付金额".$usermoneydata["money2"]."元，小时数正常返回，微信返回费用".$usermoneydata["money2"]."元";
                            $updata['income'] = 0;
                            $updata['return_money'] = $info['all_money'];//退款金额
                        }


                        //添加消费日志
                        $eff3 = db("user_money_log")->insert($moneylog);
                        $userhours = $userinfo['hours'];
                        //修改账户余额 小时卡
                        $usermoney["hours"] =$userhours + $usermoneydata['money'];
                        $usermoney['updatetime'] = time();
                        $eff4 = db("user")->where(['id'=>$info['user_id']])->update($usermoney);

                        //准备退款数据
                        //执行退款
                        $updata["upd_time"] = $time;
                        $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                        $updata["refund_number"] = $refund_number;

                        if($remoney > 0){
                            $updata["refund_status"] = 2;//申请退款中
                            //更新订单数据
                            $eff5 = db("order")->where("id={$info['id']}")->update($updata);
                            $refundRes = $this->submitDrawBack($info["all_money"],$remoney ,$info["order_number"],$refund_number,$info["transaction_id"],$info['user_id']);
                            file_put_contents("refundadmin.json",var_export($refundRes,true).PHP_EOL,FILE_APPEND);

                            //#todo 这里理论上还应该考虑 退款后 积分回退的逻辑，暂时先不考虑
                            if ($refundRes['RETURN_CODE'] == 'SUCCESS' && $refundRes['RESULT_CODE'] == 'SUCCESS') {
                                file_put_contents("refundadminsuc.json",var_export($refundRes,true));
                                //退款成功 修改订单状态
                                $updata2["refund_status"] = 3;
                                $updata2["pay_status"] = "4";//已经取消
                                $updata2["upd_time"] = time();
                                $eff6 = db("order")->where(["id"=>$info["id"]])->update($updata2);

                                if($eff1 && $eff2 && $eff3 && $eff4 && $eff5 && $eff6){
                                    //取消成功后发送短信
                                    //发送酒店
                                    if($info["h_phone"] && $info["user_name"]){
                                        sendmsgHCancel($info["h_phone"],$info["user_name"],$money);
                                    }
                                    //发送给用户
                                    if($info["user_phone"] && $info["h_phone"]){
                                        sendmsgUCancel($info["user_phone"],$money,$info["h_phone"]);
                                    }

                                    Db::commit();
                                    $this->success("订单取消成功,退款成功，请核实");
                                }else{
                                    Db::rollback();
                                    $this->error("订单取消失败");
                                }

                            }else{
                                file_put_contents("refunderr.json",var_export($refundRes,true).PHP_EOL,FILE_APPEND);
                                $msg = "退款失败";
                                Db::rollback();
                                $this->error($msg);
                            }

                        }else{
                            $updata["refund_status"] = 1;//抵消 不走退款
                            //更新订单数据
                            $eff5 = db("order")->where("id={$info['id']}")->update($updata);
                            if($eff1 && $eff2 && $eff3 && $eff4 && $eff5){
                                //取消成功后发送短信
                                //发送酒店
                                if($info["h_phone"] && $info["user_name"]){
                                    sendmsgHCancel($info["h_phone"],$info["user_name"],$money);
                                }
                                //发送给用户
                                if($info["user_phone"] && $info["h_phone"]){
                                    sendmsgUCancel($info["user_phone"],$money,$info["h_phone"]);
                                }

                                Db::commit();
                                $this->success("订单取消成功，支付的金额刚好抵扣超时取消，无需退款");
                            }else{
                                Db::rollback();
                                $this->error("订单取消失败");
                            }

                        }




                    }


                }


            }else{
                $this->error("订单数据有误");
            }
        }

    }


    //批量执行退款 处理
    public function doreturnpriceold(){
        if ($this->request->isPost()) {
            $params = $this->request->post();

            try{
                $ids = $params["Oids"];

                $orlist = db("order")->field("id,user_id,transaction_id,order_number,all_money,pay_status,return_money,refund_status,refund_number")->where(["pay_status"=>1,"refund_status"=>2])->where("id", 'in', $ids)->select();


                if($orlist){

                    foreach ($orlist as $v){
                        if($v["refund_number"] == ""){
                            $msg = "该订单".$v["order_number"]."还没有申请退款，请先申请退款";
                            $this->error($msg);
                        }

                        //调用退款接口
                        $refundRes = $this->submitDrawBack($v["all_money"],$v["return_money"],$v["order_number"],$v["refund_number"],$v["transaction_id"],$v["user_id"]);

                        if ($refundRes['RETURN_CODE'] == 'SUCCESS' && $refundRes['RESULT_CODE'] == 'SUCCESS') {
                            //退款成功 修改订单状态
                            $updata["refund_status"] = 3;
                            $updata["pay_status"] = 4;//已经取消
                            $updata["upd_time"] = time();

                            db("order")->where(["id"=>$v["id"]])->update($updata);

                        }else{
                            $msg = "该订单".$v["order_number"]."退款失败";
                            $this->error($msg);
                        }

                    }

                    $this->success("退款成功，请用户稍后核实退款是否到账");

                }else{
                    $this->error("没有找到需要退款的订单");
                }

            }catch (\think\exception\PDOException $e){

                $this->error($e->getMessage());
            }


        }

    }



    //后台进行退款接口
    //退款开始
    public function submitDrawBack($all_money,$return_money,$out_trade_no,$refund_number,$transaction_id,$user_id){

        //通过微信api进行退款流程
        $nonce_str = WxPay::str_rand();//随机32位字符串
        $total_fee = $all_money * 100;//总金额，单位：分
       // $total_fee= 0.01 * 100;//测试 一分钱
        $refund_fee = $return_money * 100;//退款金额，单位：分
       // $refund_fee= 0.01 * 100;//测试 一分钱
        $parma = array(
            'appid'=> WxPay::appid,
            'mch_id'=> WxPay::mch_id,
            'nonce_str'=> $nonce_str,
            'out_trade_no'=> $out_trade_no,//小程序自定义订单号，支付时后台生成
            'out_refund_no'=> $refund_number,
            'refund_fee'=> $refund_fee,
            'total_fee'=> $total_fee,
            'transaction_id' => $transaction_id,//小程序平台订单号，微信平台生成
        );

        $KEY = WxPay::key;//小程序支付秘钥
        $parma['sign'] = $this->getSign($parma, $KEY);

        $post_xml = $this->arrayToXml($parma);//把参数转化成xml格式

        //向微信平台api发送退款参数
        $xmlresult = $this->postXmlSSLCurl($post_xml,'https://api.mch.weixin.qq.com/secapi/pay/refund');

        //解析返回的参数
        $array = $this->xml2array($xmlresult);
        //两个success表示退款成功，无需使用回调，在此进行逻辑处理即可

        return $array;

    }
    //需要使用证书的请求
    function postXmlSSLCurl($xml,$url,$second=30)
    {
        //使用的啊里云宝塔，存放证书路径，放在public中，新建cert

        $cert = '/www/wwwroot/minsuceshi/public/cert/apiclient_cert.pem';
        $key = '/www/wwwroot/minsuceshi/public/cert/apiclient_key.pem';
//        $cert = 'C:\Users\Administrator\Desktop\1602911873_20201017_cert/apiclient_cert.pem';
//         $key = 'C:\Users\Administrator\Desktop\1602911873_20201017_cert/apiclient_key.pem';
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        //这里设置代理，如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //设置证书
        //使用证书：cert 与 key 分别属于两个.pem文件
        //默认格式为PEM，可以注释,使用getcwd()方法，拼接证书的绝对路径
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT,$cert);

        //默认格式为PEM，可以注释,使用getcwd()方法，拼接证书的绝对路径
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY,$key);

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, true);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

        $data = curl_exec($ch);

//        p($data);die;
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            echo "curl出错，错误码:$error" . "<br>";
            curl_close($ch);
            return false;
        }
    }
    //退款结束
    //获取xml里面数据，转换成array
    private function xml2array($xml)
    {
        $p = xml_parser_create();
        xml_parse_into_struct($p, $xml, $vals, $index);
        xml_parser_free($p);
        $data = [];

        foreach ($index as $key => $value) {
            if ($key == 'xml' || $key == 'XML') continue;
            $tag = $vals[$value[0]]['tag'];
            $value = $vals[$value[0]]['value'];
            $data[$tag] = $value;
        }
        return $data;
    }
    //数组转字符串方法
    protected function arrayToXml($arr){
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {

            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
    protected function getSign($params, $key)
    {
        ksort($params, SORT_STRING);
        $unSignParaString = $this->formatQueryParaMap($params, false);
        return $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
    }
    protected function formatQueryParaMap($paraMap, $urlEncode = false)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v) {
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }




}
